﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ERPStore.Services
{
	public class PushSubscriberService : IDisposable
	{
		private SynchronizedCollection<ERPStore.Models.PushSubscriber> m_Subscribers;

		public PushSubscriberService()
		{
			m_Subscribers = new SynchronizedCollection<ERPStore.Models.PushSubscriber>();
		}

		public void Add(Models.PushSubscriber subscriber)
		{
			lock (m_Subscribers.SyncRoot)
			{
				m_Subscribers.Add(subscriber);
			}
		}

		public void WriteMessage(string message)
		{
			var closedList = new List<string>();
			lock (m_Subscribers.SyncRoot)
			{
				foreach (var subscriber in m_Subscribers)
				{
					try
					{
						subscriber.StreamWriter.Write(message);
						subscriber.StreamWriter.Flush();
						subscriber.LastWriteDate = DateTime.Now;
					}
					catch
					{
						closedList.Add(subscriber.Id);
					}
				}
			}
			var idleSubscriberListId = m_Subscribers.Where(i => i.LastWriteDate.AddMinutes(5) < DateTime.Now).Select(i => i.Id).ToList();
			closedList.AddRange(idleSubscriberListId);
			if (closedList.Count > 0)
			{
				foreach (var subscriberId in closedList)
				{
					var subscriber = m_Subscribers.SingleOrDefault(i => i.Id == subscriberId);
					if (subscriber == null)
					{
						continue;
					}
					KillSubscriber(subscriber);
				}
			}
		}

		private void KillSubscriber(ERPStore.Models.PushSubscriber s)
		{
			try
			{
				s.StreamWriter.Close();
				s.StreamWriter.Dispose();
			}
			catch
			{

			}
			finally
			{
				lock (m_Subscribers)
				{
					m_Subscribers.Remove(s);
				}
			}
		}

		#region IDisposable Members

		public void Dispose()
		{
			if (m_Subscribers != null)
			{
				var subscriberIdList = m_Subscribers.Select(i => i.Id).ToList();
				lock (m_Subscribers.SyncRoot)
				{
					foreach (var item in subscriberIdList)
					{
						var s = m_Subscribers.Single(i => i.Id == item);
						KillSubscriber(s);
					}
				}
			}
		}

		#endregion
	}
}
